package com.hxkcloud.patient.aerotel.domain.health;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.widget.Toast;


import com.hxkcloud.patient.aerotel.log.AppLogger;
import com.hxkcloud.patient.aerotel.util.DateUtil;
import com.hxkcloud.patient.aerotel.util.FileHelper;
import com.hxkcloud.patient.aerotel.util.HexUtil;
import com.hxkcloud.patient.aerotel.util.ImageResizer;
import com.hxkcloud.patient.aerotel.util.TypeConvert;
import com.hxkcloud.patient.aerotel.util.UUIDUtil;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.achartengine.model.XYMultipleSeriesDataset;
import org.achartengine.model.XYSeries;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Locale;
import java.util.Map;
import java.util.TreeMap;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

/**
 * Created by daipengfei on 16/3/3.
 * Changed by songyuequan on ·6/12/27.
 */
public class AerotelECGPdu {
    public static final byte BT_ACK = 0x06;//数据不会删除  断开连接
    public static final byte BT_ETX = 0x03; //数据删除  断开连接
    //    If the Checksum test failed, the HVM will send <NAK> (0x15h)
// to force the HeartView P12/8BT to resend the Header Packet.
    public static final byte BT_NAK = 0x15;

    public static final byte BT_STX = 0x02;//开始传输
    public static final int NUMBEROF_PACKETS = 220;
    public static final int SIZEOF_AP_HEADER = 60;
    public static final int SIZEOF_DATA = 14740;
    public static final int SIZEOF_DATA_LINE = 67;   //数据一共多少行
    public static final int SIZEOF_ECG = 14080;     //纯心电图数据大小    拆12组   Base64
    public static final int SIZEOF_LEAD = 938;      //其他数据
    public static final int SIZEOF_LEAD_II = 3750;  //二导数据

    private static final String[] CONST_XML_PARTS = {"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ECG>\n<HRR Version=\"3\"/>\n<Patient>\n<Category Type=\"String\" Value=\"", "\"/>\n<UserCode Type=\"String\" Value=\"", "\"/>\n<DBUser Type=\"String\" Value=\"", "\" />\n</Patient>\n<DeviceInfo>\n<SN Type=\"String\" Value=\"", "\"/>\n<MonitorCode Type=\"String\" Value=\"6\"/>\n<MonitorType Type=\"String\" Value=\"P12-BT\"/>\n<Firmware Type=\"String\" Value=\"2.5\"/>\n<BTAddress Type=\"String\" Value=\"", "\"/>\n<BTFirmware Type=\"String\" Value=\"", "\"/>\n<BatteryVoltage Type=\"Decimal\" Value=\"0\"/>\n<Manufacturer Type=\"String\" Value=\"Aerotel Medical Systems\"/>\n", "</DeviceInfo>\n<Events EventCount=\"1\">\n<Event  EventNo=\"1\">\n<ECGInfo>\n<SRate Type=\"Decimal\" Value=\"375\"/>\n<ADU Type=\"Decimal\" Value=\"51.20\"/>\n", "<Multiplier Type=\"Decimal\" Value=\"19.53125\"/>\n<DataType Type=\"String\" Value=\"byte\"/>\n<Baseline Type=\"Decimal\" Value=\"128\"/>\n<SwitchPosition Type=\"String\" Value=\"", "\"/>\n<DateTime Type=\"String\" Value=\"", "\"/>\n<ElapsedSeconds Type=\"Decimal\" Value=\"", "\"/>\n<HighPassFilter Type=\"Decimal\" Value=\"0.05\"/>\n<LowPassFilter Type=\"Decimal\" Value=\"150\"/>\n<NotchFilter Type=\"Decimal\" Value=\"\"/>\n", "<Pacemaker Type =\"Boolean\" Value=\"False\"/>\n<LeadCount Type=\"Decimal\" Value=\"12\"/>\n<LeadLengths Type=\"String\" Value=\"3750,938,938,938,938,938,938,938,938,938,938,938\"/>\n", "<LeadNames Type=\"String\" Value=\"II,I,III,aVR,aVL,aVF,V1,V2,V3,V4,V5,V6\"/>\n</ECGInfo>\n<ECGData>\n", "<II  Type=\"hexbinary\" Value=\"", "\"/>\n<I   Type=\"hexbinary\" Value=\"", "\"/>\n<III Type=\"hexbinary\" Value=\"", "\"/>\n<aVR Type=\"hexbinary\" Value=\"", "\"/>\n<aVL Type=\"hexbinary\" Value=\"", "\"/>\n<aVF Type=\"hexbinary\" Value=\"", "\"/>\n<V1  Type=\"hexbinary\" Value=\"", "\"/>\n<V2  Type=\"hexbinary\" Value=\"", "\"/>\n<V3  Type=\"hexbinary\" Value=\"", "\"/>\n<V4  Type=\"hexbinary\" Value=\"", "\"/>\n<V5  Type=\"hexbinary\" Value=\"", "\"/>\n<V6  Type=\"hexbinary\" Value=\"", "\"/>\n</ECGData>\n<EventInfo>\n<Symptoms Type=\"String\" Value=\"\"/><Diagnosis Type=\"String\" Value=\"\"/><Remarks Type=\"String\" Value=\"\"/></EventInfo>\n</Event>\n</Events>\n</ECG>\n"};
    private static final String TAG = AerotelECGPdu.class.getSimpleName();

    public long id;
    public String devicename;
    public String devicesn;
    public String devicebtmac;
    public String createdDate;
    public String file;
    public int state = 0;//1 代表上传成功，-1代表失败 0代表没有走上传接口
    private String xmlCreatedDate;

    public AerotelECGPdu() {
    }


    /**
     * 本地保存数据 上传
     *
     * @param context
     */
    public void save2local(Context context) {
        this.createdDate = DateUtil.now("yyyy-MM-dd HH:mm:ss");
        this.xmlCreatedDate = DateUtil.now("yyyyMMdd HH:mm:ss");
        String[] split = this.xmlCreatedDate.split(" ");
        this.xmlCreatedDate = split[0] + "T" + split[1];
        this.file = UUIDUtil.generate();
        this.devicesn = this.header.getDeviceSN();
        File dir = context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
        if (!dir.exists()) {
            boolean b = dir.mkdirs();
            AppLogger.i("创建目录：" + b);
        }
        String file = dir.getAbsolutePath() + File.separator + this.file + ".xml";
        String xml = this.buildxml3();
//        String json = this.bulidJson(context);
        FileHelper.write(file, xml);

        try {//生成心电图的图片   每一个字节是一个电压  最高的电压是5毫伏     256个点     -128~128
            String imgfile = dir.getAbsolutePath() + File.separator + this.file + ".jpg";
            ECGDrawer drawer = new ECGDrawer();
            this.loadxml(new FileInputStream(file));
            Bitmap bitmap = drawer.draw(this);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(imgfile));
            ImageResizer imgr = new ImageResizer();
            imgr.maxHeight = 200;
            imgr.maxWidth = 200;
            Bitmap thumb = imgr.transform(bitmap);
            String thumbf = dir.getAbsolutePath() + File.separator + this.file + "-m.jpg";
            thumb.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(thumbf));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            AppLogger.e("Save As ECG Drawer to local", e);
        }
        //保存本地数据库
        ECGManager.create(context, this);
//        uploadByMqtt(json);
        //上传至云端
//        UploadTask task = new UploadTask(context, this);
//        task.execute(this.id);
    }
//
//    private void uploadByMqtt(String json) {
//        try {
//            MQTTClient mqttClient = new MQTTClient();
////           String josn = "[{\"CityId\":18,\"CityName\":\"西安\",\"ProvinceId\":27,\"CityOrder\":1},{\"CityId\":53,\"CityName\":\"广州\",\"ProvinceId\":27,\"CityOrder\":1}]";
//            Log.e(TAG, "sent message mqtt");
//            MqttClient mqttClient1 = mqttClient.deviceConnect();//开启mqtt/
//            mqttClient.sendMessage(mqttClient1, json);
//        } catch (Exception e){
//            e.printStackTrace();
//        }
//    }

    public Bitmap getThumbImage(Context context) {
        File dir = context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
        String thumbf = dir.getAbsolutePath() + File.separator + this.file + "-m.jpg";
        Bitmap thumb = BitmapFactory.decodeFile(thumbf);
        return thumb;
    }

    public void loadfile(Context context) {
        File dir = context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
        String file = dir.getAbsolutePath() + File.separator + this.file + ".xml";
        try {
            FileInputStream fis = new FileInputStream(file);
            loadxml(fis);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            Toast.makeText(context, "心电图文件未找到", Toast.LENGTH_SHORT).show();
        }
    }

    public String getPicturePath(Context context) {
        File dir = context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
        return dir.getAbsolutePath() + File.separator + this.file + ".jpg";
    }

    /**
     * 蓝牙头信息
     */
    public static class Header {
        String device;
        public byte[] header = null;
        /**
         * 2bytes
         */
        public byte[] PacketType = new byte[2];
        /**
         * 4bytes
         */
        public byte[] DataLength = new byte[4];
        /**
         * 2bytes
         */
        public byte[] DeviceType = new byte[2];

        public byte ECGType;
        /**
         * 9bytes,terminated by <CR>(0x0D)
         */
        public byte[] DeviceSN = new byte[8];
        /**
         * 1byte,empty 1 byte
         */
        public byte TimeOffset;
        /**
         * reserved 4 bytes
         */
        public byte[] Reserved = new byte[4];
        /**
         * ASCII,12bytes
         */
        public byte[] BluetoothID = new byte[12];
        public byte[] BTFirmwareVer = new byte[19];
        public byte[] TimeElapsed = new byte[4];
        public byte DeviceFirmwareVer;

        public Header() {
        }

        public Header(byte[] header) {
            this.header = header;

            PacketType[0] = header[0];
            PacketType[1] = header[1];

            DataLength[0] = header[2];
            DataLength[1] = header[3];
            DataLength[2] = header[4];
            DataLength[3] = header[5];

            DeviceType[0] = header[6];
            DeviceType[1] = header[7];

            ECGType = header[8];

            DeviceSN[0] = header[9];
            DeviceSN[1] = header[10];
            DeviceSN[2] = header[11];
            DeviceSN[3] = header[12];
            DeviceSN[4] = header[13];
            DeviceSN[5] = header[14];
            DeviceSN[6] = header[15];
            DeviceSN[7] = header[16];
            //header[17] is <CR>

            TimeOffset = header[18];

            Reserved[0] = header[19];
            Reserved[1] = header[20];
            Reserved[2] = header[21];
            Reserved[3] = header[22];

            BluetoothID[0] = header[23];
            BluetoothID[1] = header[24];
            BluetoothID[2] = header[25];
            BluetoothID[3] = header[26];
            BluetoothID[4] = header[27];
            BluetoothID[5] = header[28];
            BluetoothID[6] = header[29];
            BluetoothID[7] = header[30];
            BluetoothID[8] = header[31];
            BluetoothID[9] = header[32];
            BluetoothID[10] = header[33];
            BluetoothID[11] = header[34];

            int p = 35;
            for (int i = 0; i < 19; i++) {
                BTFirmwareVer[i] = header[p];
                p++;
            }

            p++;

            for (int i = 0; i < 4; i++) {
                TimeElapsed[i] = header[p];
                p++;
            }

            DeviceFirmwareVer = header[p];
        }

        public String getECGType() {
            byte[] etype = new byte[]{ECGType};
            return new String(etype);
        }

        public int getTime() {
            String t = HexUtil.toHex(TimeElapsed);
            int time = Integer.parseInt(t);
            return time * 60 + this.TimeOffset;
        }

        public String getDeviceSN() {
//            try {
//                device = new String(this.DeviceSN, "GBK");
//            } catch (UnsupportedEncodingException e) {
//                e.printStackTrace();
//            }
            return new String(this.DeviceSN);
        }

        public String getBluetoothID() {
            String t = HexUtil.toHex(this.BluetoothID);
            return t;
//            return new String(this.BluetoothID);
        }

        public int getDataLength() {
            int len = TypeConvert.byte2int(DataLength);
            return len;
        }

        public String getBTFW() {
            String btfw = new String(BTFirmwareVer);
            btfw = btfw.substring(0, btfw.indexOf(13));
            return btfw;
        }

        public String getFW() {
            return new String(new byte[]{DeviceFirmwareVer});
        }
    }

    public final static String LEAD_II = "II";
    public final static String LEAD_I = "I";
    public final static String LEAD_III = "III";
    public final static String LEAD_AVR = "aVR";
    public final static String LEAD_AVL = "aVL";
    public final static String LEAD_AVF = "aVF";
    public final static String LEAD_V1 = "V1";
    public final static String LEAD_V2 = "V2";
    public final static String LEAD_V3 = "V3";
    public final static String LEAD_V4 = "V4";
    public final static String LEAD_V5 = "V5";
    public final static String LEAD_V6 = "V6";

    /**
     * 所有的数据
     */
    public static class Data {

        public byte[] data = null;
        public ByteArrayOutputStream baos = new ByteArrayOutputStream();

        public Map<String, byte[]> leadValues = new TreeMap<>();//用来装数据的集合。

        public Data() {
        }

        public Data(byte[] data) {
            this.data = data;
        }

        public boolean checksum() {
            AppLogger.d("checking CRC");
            if (data.length != 14740) {//检验数据的长度
                AppLogger.d("data.length = " + data.length + ". less then " + 14740);
                baos.reset();//长度不符合，清空数据
                return false;
            }
            for (int i = 0; i < NUMBEROF_PACKETS; i++) {
                int m = i * 67;

                baos.write(data, m, 64);//每次写入64个字节    还剩三个？？？？？

                int k = 0;
                for (int j = 0; j < 64; j++) {//把每一行所有的数据都加起来
                    k = (byte) (data[(j + m)] + k);
                }
                AppLogger.d("line " + i + ". CRC is " + k + ". CRC form data is " + data[(m + 64)] + ". byte 65 is " + data[(m + 65)] + ". byte 66 is " + data[(m + 66)]);
                //TODO   65  66  67 ?
                boolean b = (k == data[(m + 64)]) && (data[(m + 65)] == 13) && (data[(m + 66)] == 10);
                if (!b) {
                    baos.reset();
                    return false;
                }
            }
            byte[] bytes = baos.toByteArray();
            int p = 0;
            leadValues.put(LEAD_II, Arrays.copyOfRange(bytes, p, p + 3750));
            p += 3750;
            leadValues.put(LEAD_I, Arrays.copyOfRange(bytes, p, p + 938));
            p += 938;
            leadValues.put(LEAD_III, Arrays.copyOfRange(bytes, p, p + 938));
            p += 938;
            leadValues.put(LEAD_AVR, Arrays.copyOfRange(bytes, p, p + 938));
            p += 938;
            leadValues.put(LEAD_AVL, Arrays.copyOfRange(bytes, p, p + 938));
            p += 938;
            leadValues.put(LEAD_AVF, Arrays.copyOfRange(bytes, p, p + 938));
            p += 938;
            leadValues.put(LEAD_V1, Arrays.copyOfRange(bytes, p, p + 938));
            p += 938;
            leadValues.put(LEAD_V2, Arrays.copyOfRange(bytes, p, p + 938));
            p += 938;
            leadValues.put(LEAD_V3, Arrays.copyOfRange(bytes, p, p + 938));
            p += 938;
            leadValues.put(LEAD_V4, Arrays.copyOfRange(bytes, p, p + 938));
            p += 938;
            leadValues.put(LEAD_V5, Arrays.copyOfRange(bytes, p, p + 938));
            p += 938;
            leadValues.put(LEAD_V6, Arrays.copyOfRange(bytes, p, p + 938));

            return true;
        }

        public boolean inflate(byte[] bytes) {
            if (bytes == null || bytes.length != 14080) {
                return false;
            }
            int p = 0;
            leadValues.put(LEAD_II, Arrays.copyOfRange(bytes, p, p + 3750));
            p += 3750;
            leadValues.put(LEAD_I, Arrays.copyOfRange(bytes, p, p + 938));
            p += 938;
            leadValues.put(LEAD_III, Arrays.copyOfRange(bytes, p, p + 938));
            p += 938;
            leadValues.put(LEAD_AVR, Arrays.copyOfRange(bytes, p, p + 938));
            p += 938;
            leadValues.put(LEAD_AVL, Arrays.copyOfRange(bytes, p, p + 938));
            p += 938;
            leadValues.put(LEAD_AVF, Arrays.copyOfRange(bytes, p, p + 938));
            p += 938;
            leadValues.put(LEAD_V1, Arrays.copyOfRange(bytes, p, p + 938));
            p += 938;
            leadValues.put(LEAD_V2, Arrays.copyOfRange(bytes, p, p + 938));
            p += 938;
            leadValues.put(LEAD_V3, Arrays.copyOfRange(bytes, p, p + 938));
            p += 938;
            leadValues.put(LEAD_V4, Arrays.copyOfRange(bytes, p, p + 938));
            p += 938;
            leadValues.put(LEAD_V5, Arrays.copyOfRange(bytes, p, p + 938));
            p += 938;
            leadValues.put(LEAD_V6, Arrays.copyOfRange(bytes, p, p + 938));
            return true;
        }

        public byte[] getData() {
            byte[] bytes = baos.toByteArray();
            return bytes;
        }

        public byte[] getLeadData(String lead) {
            return leadValues.get(lead);
        }

        public String getLeadDataHex(String lead) {//转换成Hex保存到XMl中
            byte[] values = leadValues.get(lead);
//            String xvalues = HexUtil.toHex(values);
            String xvalues2 = HexUtil.toHex2(values);
            return xvalues2;
        }

        public XYSeries getXYSeries(String lead) {
            byte[] values = getLeadData(lead);
            if (values != null) {
                XYSeries series = new XYSeries(lead);
                int size = values.length;
                for (int i = 0; i < size; i++) {
                    int y = values[i];
                    if (y > 128) y -= 128; //?
                    series.add(i, y);
                }
                return series;
//                return regularToCenteredGraph(series);
            }
            return null;
        }


        private XYSeries regularToCenteredGraph(XYSeries paramXYSeries) {
            XYSeries localXYSeries = new XYSeries(paramXYSeries.getTitle());
            double d1 = paramXYSeries.getMaxY();
            double d2 = paramXYSeries.getMinY();
            d1 = -((d1 - d2) / 2.0D + d2);

            for (int i = 0; i < paramXYSeries.getItemCount(); i++) {
                localXYSeries.add(paramXYSeries.getX(i), paramXYSeries.getY(i) + d1);
            }
            return localXYSeries;
        }

        public XYMultipleSeriesDataset getChartDataSet(String lead) {
            XYSeries series = getXYSeries(lead);
            if (series != null) {
                XYMultipleSeriesDataset dataset = new XYMultipleSeriesDataset();
                dataset.addSeries(series);
                return dataset;
            }
            return null;
        }
    }

    public Header header = new Header();
    public Data data = new Data();

    public String buildxml() {
        String ecgtype = "8";
        if (this.header.ECGType == 2) {
            ecgtype = "12";
        }
        String str = Integer.toString(this.header.getTime());

        StringBuilder sb = new StringBuilder();
        sb.append(CONST_XML_PARTS[0]).append("").append(CONST_XML_PARTS[1]).append("").append(CONST_XML_PARTS[2]).append("").append(CONST_XML_PARTS[3]).append(this.header.getDeviceSN()).append(CONST_XML_PARTS[4]).append(this.header.getBluetoothID().replace(":", "")).append(CONST_XML_PARTS[5]).append(this.header.getBTFW()).append(CONST_XML_PARTS[6]).append(CONST_XML_PARTS[7]).append(CONST_XML_PARTS[8]).append(this.header.getBluetoothID()).append(CONST_XML_PARTS[9]).append(str).append(CONST_XML_PARTS[10]).append(str).append(CONST_XML_PARTS[11]).append(CONST_XML_PARTS[12]).append(CONST_XML_PARTS[13]);
        byte[] ecgdata = data.getData();
        sb.append(CONST_XML_PARTS[14]).append(data.getLeadDataHex(LEAD_II)).append(CONST_XML_PARTS[15]);
        int i = 3750;
        sb.append(data.getLeadDataHex(LEAD_I)).append(CONST_XML_PARTS[16]);
        i += 938;
        sb.append(data.getLeadDataHex(LEAD_III)).append(CONST_XML_PARTS[17]);
        i += 938;
        sb.append(data.getLeadDataHex(LEAD_AVR)).append(CONST_XML_PARTS[18]);
        i += 938;
        sb.append(data.getLeadDataHex(LEAD_AVL)).append(CONST_XML_PARTS[19]);
        i += 938;
        sb.append(data.getLeadDataHex(LEAD_AVF)).append(CONST_XML_PARTS[20]);
        i += 938;
        sb.append(data.getLeadDataHex(LEAD_V1)).append(CONST_XML_PARTS[21]);
        i += 938;
        sb.append(data.getLeadDataHex(LEAD_V2)).append(CONST_XML_PARTS[22]);
        i += 938;
        sb.append(data.getLeadDataHex(LEAD_V3)).append(CONST_XML_PARTS[23]);
        i += 938;
        sb.append(data.getLeadDataHex(LEAD_V4)).append(CONST_XML_PARTS[24]);
        i += 938;
        sb.append(data.getLeadDataHex(LEAD_V5)).append(CONST_XML_PARTS[25]);
        i += 938;
        sb.append(data.getLeadDataHex(LEAD_V6)).append(CONST_XML_PARTS[26]);
        AppLogger.i(String.valueOf(i));
        String xml = sb.toString();
        return xml;
    }


    public String buildxml3() {
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();  //取得DocumentBuilderFactory实例
            DocumentBuilder builder = factory.newDocumentBuilder(); //从factory获取DocumentBuilder实例
            Document doc = builder.newDocument();
            doc.setXmlVersion("1.0");

            Element root = doc.createElement("ECG");
            doc.appendChild(root);
//            <Version Type="String">1.0</Version>
            Element version = doc.createElement("Version");
            version.setAttribute("Type", "String");
            version.setTextContent("1.0");
            root.appendChild(version);
//------------------  <DeviceInfo>-------------------
            Element deviceInfo = doc.createElement("DeviceInfo");
            root.appendChild(deviceInfo);

            Element sn = doc.createElement("SN");
            sn.setAttribute("Type", "String");
            sn.setAttribute("Value", header.getBluetoothID());
            deviceInfo.appendChild(sn);

            Element manufacturer = doc.createElement("Manufacturer");
            manufacturer.setAttribute("Type", "String");
            manufacturer.setAttribute("Value", "Aerotel Medical Systems");
            deviceInfo.appendChild(manufacturer);


/*----------------<Events EventCount="1">-----------------*/

            Element events = doc.createElement("Events");
            events.setAttribute("EventCount", "1");
            root.appendChild(events);
//-----------------------Event----------------------------
            Element event = doc.createElement("Event");
            event.setAttribute("EventNo", "1");
            events.appendChild(event);
//-----------------------ECGInfo----------------------------
            Element ecgInfo = doc.createElement("ECGInfo");
            event.appendChild(ecgInfo);

            Element SRate = doc.createElement("SRate");
            SRate.setAttribute("Type", "Decimal");
            SRate.setAttribute("Value", "375");
            ecgInfo.appendChild(SRate);

            Element ADU = doc.createElement("ADU");
            ADU.setAttribute("Type", "Decimal");
            ADU.setAttribute("Value", "51.20");
            ecgInfo.appendChild(ADU);

            Element DataType = doc.createElement("DataType");
            DataType.setAttribute("Type", "String");
            DataType.setAttribute("Value", "byte");
            ecgInfo.appendChild(DataType);

            Element Baseline = doc.createElement("Baseline");
            Baseline.setAttribute("Type", "Decimal");
            Baseline.setAttribute("Value", "128");
            ecgInfo.appendChild(Baseline);

            Element dateTime = doc.createElement("DateTime");
            dateTime.setAttribute("Type", "String");
            dateTime.setAttribute("Value", xmlCreatedDate);
            ecgInfo.appendChild(dateTime);


            Element leadCount = doc.createElement("LeadCount");
            leadCount.setAttribute("Type", "Decimal");
            leadCount.setAttribute("Value", "12");
            ecgInfo.appendChild(leadCount);


            Element leadLengths = doc.createElement("LeadLengths");
            leadLengths.setAttribute("Type", "String");
            leadLengths.setAttribute("Value", "3750,938,938,938,938,938,938,938,938,938,938,938");
            ecgInfo.appendChild(leadLengths);

            Element leadNames = doc.createElement("LeadNames");
            leadNames.setAttribute("Type", "String");
            leadNames.setAttribute("Value", "II,I,III,aVR,aVL,aVF,V1,V2,V3,V4,V5,V6");
            ecgInfo.appendChild(leadNames);


//----------------------------ECGData----------------------------------------
            Element ecgData = doc.createElement("ECGData");
            event.appendChild(ecgData);
            String[] leads = {LEAD_II,
                    LEAD_I,
                    LEAD_III,
                    LEAD_AVR,
                    LEAD_AVL,
                    LEAD_AVF,
                    LEAD_V1,
                    LEAD_V2,
                    LEAD_V3,
                    LEAD_V4,
                    LEAD_V5,
                    LEAD_V6};
            for (String lead : leads) {
                Element item = doc.createElement(lead);
                String value = data.getLeadDataHex(lead);
                item.setAttribute("Type", "hexbinary");
                item.setAttribute("Value", value);
                ecgData.appendChild(item);
            }
            TransformerFactory transFactory = TransformerFactory.newInstance();
            Transformer transFormer = transFactory.newTransformer();
            DOMSource domSource = new DOMSource(doc);

            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            transFormer.transform(domSource, new StreamResult(bos));
            String xml = bos.toString();
            return xml;
        } catch (Exception ex) {
            AppLogger.e("Parse XML Exception", ex);
        }

        return null;
    }


    public String buildxml2() {
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();  //取得DocumentBuilderFactory实例
            DocumentBuilder builder = factory.newDocumentBuilder(); //从factory获取DocumentBuilder实例
            Document doc = builder.newDocument();

            doc.setXmlVersion("1.0");

            Element root = doc.createElement("ECG");
            doc.appendChild(root);

            Element device = doc.createElement("device");
//            device.setAttribute("sn", header.getDeviceSN());
            device.setAttribute("mac", header.getBluetoothID());
            device.setAttribute("btfw", header.getBTFW());
//            device.setAttribute("fw", header.getFW());
            device.setAttribute("type", header.getECGType());
            root.appendChild(device);

            Element descriptor = doc.createElement("descriptor");
            descriptor.setAttribute("srate", "375");
            descriptor.setAttribute("leads", "II,I,III,aVR,aVL,aVF,V1,V2,V3,V4,V5,V6");
            descriptor.setAttribute("length", "3750,938,938,938,938,938,938,938,938,938,938,938");
            descriptor.setAttribute("duration", "10,2.5,2.5,2.5,2.5,2.5,2.5,2.5,2.5,2.5,2.5,2.5");
            root.appendChild(descriptor);

            Element ecgdata = doc.createElement("data");
            root.appendChild(ecgdata);
            String[] leads = {LEAD_II,
                    LEAD_I,
                    LEAD_III,
                    LEAD_AVR,
                    LEAD_AVL,
                    LEAD_AVF,
                    LEAD_V1,
                    LEAD_V2,
                    LEAD_V3,
                    LEAD_V4,
                    LEAD_V5,
                    LEAD_V6};
            for (String lead : leads) {
                Element item = doc.createElement(lead);
                String value = data.getLeadDataHex(lead);
                item.setAttribute("Value", value);
                ecgdata.appendChild(item);
            }
            TransformerFactory transFactory = TransformerFactory.newInstance();
            Transformer transFormer = transFactory.newTransformer();
            DOMSource domSource = new DOMSource(doc);

            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            transFormer.transform(domSource, new StreamResult(bos));
            String xml = bos.toString();
            return xml;
        } catch (Exception ex) {
            AppLogger.e("Parse XML Exception", ex);
        }

        return null;
    }

    /**
     * 加载xml中的十二导联数据
     *
     * @param is
     */
    public void loadxml(InputStream is) {
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();  //取得DocumentBuilderFactory实例
            DocumentBuilder builder = factory.newDocumentBuilder(); //从factory获取DocumentBuilder实例
            Document doc = builder.parse(is);   //解析输入流 得到Document实例
            Element rootElement = doc.getDocumentElement();
            String[] leads = {LEAD_II,
                    LEAD_I,
                    LEAD_III,
                    LEAD_AVR,
                    LEAD_AVL,
                    LEAD_AVF,
                    LEAD_V1,
                    LEAD_V2,
                    LEAD_V3,
                    LEAD_V4,
                    LEAD_V5,
                    LEAD_V6};
            for (String lead : leads) {
                NodeList items = rootElement.getElementsByTagName(lead);
                for (int i = 0; i < items.getLength(); i++) {
                    Element item = (Element) items.item(i);
                    String hex = item.getAttribute("Value");
                    byte[] bytes = HexUtil.toBytes(hex);
                    this.data.leadValues.put(lead, bytes);
                }
            }
        } catch (Exception ex) {
            AppLogger.e("Parse XML Exception", ex);
        }
    }

    private String DataToHex(byte[] bytes, int offset, int len) {
        StringBuilder sb = new StringBuilder();
        if ((len <= 0) || (offset >= bytes.length)) {
            return "";
        }
        for (int i = 0; i < len; i++) {
            int j = bytes[offset + i];
            if (j >= 128) {
                j -= 128;
            }
            if (j < 16) {
                sb.append('0');
            }
            sb.append(Integer.toHexString(j).toUpperCase(Locale.ENGLISH));
        }
        return sb.toString();
    }

    public Map<String, XYMultipleSeriesDataset> getLeadDatasets() {
        Map<String, XYMultipleSeriesDataset> map = new TreeMap<>();
        map.put(LEAD_II, this.data.getChartDataSet(LEAD_II));
        map.put(LEAD_I, this.data.getChartDataSet(LEAD_I));
        map.put(LEAD_III, this.data.getChartDataSet(LEAD_III));
        map.put(LEAD_AVR, this.data.getChartDataSet(LEAD_AVR));
        map.put(LEAD_AVL, this.data.getChartDataSet(LEAD_AVL));
        map.put(LEAD_AVF, this.data.getChartDataSet(LEAD_AVF));
        map.put(LEAD_V1, this.data.getChartDataSet(LEAD_V1));
        map.put(LEAD_V2, this.data.getChartDataSet(LEAD_V2));
        map.put(LEAD_V3, this.data.getChartDataSet(LEAD_V3));
        map.put(LEAD_V4, this.data.getChartDataSet(LEAD_V4));
        map.put(LEAD_V5, this.data.getChartDataSet(LEAD_V5));
        map.put(LEAD_V6, this.data.getChartDataSet(LEAD_V6));
        return map;
    }
}
